// Copyright (C) 2012 - Will Glozer.  All rights reserved.


#include <getopt.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <sys/types.h> 
#include <fcntl.h>
#include "wrk_setproctitle.h"
#include "wrk_process.h"
#include "wrk_core.h"
#include "server.h"
#include "wrk_logger.h"
#include "include/zmalloc.h"

// static void __attribute__ ((destructor)) func_after_main()
// {
//     CDEBUG << "stop worker process";
// 	kill(getpid(), SIGTERM);
// }

char  *conf;

char *arg0;

static std::string sig;

static void process_signal(string signal);

int MAX_WORKER_PROCESS_NUM;

static struct option longopts[] = {
    { "conf",        required_argument, NULL, 'c' },
    { "signal",      required_argument, NULL, 's' },
    { "help",        no_argument,       NULL, 'h' },
    { "version",     no_argument,       NULL, 'v' },
    { NULL,          0,                 NULL,  0  }
};

static void usage() {
    printf("Usage: dist-wrk <options>                                               \n"
           "  Options:                                                              \n"
           "    -c, --conf          <Y>  config file path                           \n"
           "    -s, --signal        send signal to a master process: stop,reload    \n"
           "    -v, --version       Print version details                           \n"
           "                                                                        \n"
           "  Numeric arguments may include a SI unit (1k, 1M, 1G)                  \n"
           "  Time arguments may include a time unit (2s, 2m, 2h)                   \n");
}


static int parse_args(int argc, char **argv) {
    if(argc<2) {
        return -1;
    }

    int c;
    conf = NULL;
    while ((c = getopt_long(argc, argv, "c:s:vh?", longopts, NULL)) != -1) {
        switch (c) {
            case 'c':
                conf = optarg;
                break;
            case 's':
                sig = optarg;
                if(sig=="stop" || sig=="reload") {
                    process_signal(sig);

                }else {
                    printf("unkown signal\n");
                    return -1;
                }
                break;
            case 'v':
                printf("dist-wrk %s [%s] ", VERSION, aeGetApiName());
                printf("update by jiuguo.qin 20190707\n");
                exit(0);
                break;
            case 'h':
            case '?':
            case ':':
            default:
                return -1;
        }
    }

    return 0;
}

static void process_signal(string signal)
{
    ifstream lockfile(LOCKFILE,ios::in);
    if(!lockfile) {
        printf("can't open %s, error:%s\n", LOCKFILE, strerror(errno));
        exit(-1);
    }

    string line;
    getline(lockfile, line);
    pid_t pid;
    stringstream ss;
    ss << line;
    ss >> pid;
    if(pid <=0) {
        printf("invaild pid in %s\n", LOCKFILE);
        exit(-1);
    }

    if(sig == "stop") {
        if(kill(pid, SIGTERM)) {
            printf("send SIGTERM to pid:%d error, %s\n", pid, strerror(errno));
        }
    } else if(sig == "reload") {
        // if(kill(pid, SIGUSR2)) {
        //     printf("send SIGUSR1 to pid:%d error, %s\n", pid, strerror(errno));
        // }
    }

    exit(0);
}



int main(int argc, char **argv) 
{
    arg0 = argv[0];
    wrk_save_argv(argc, argv);

    if(parse_args(argc, argv) || conf==NULL) {
        usage();
        exit(1);
    }
    
    server *p = new server();
    p->run(conf);
    return 0;
}

